from flask import current_app, g
from flask_jwt_extended import jwt_required
from flask_restx import Namespace, Resource, fields, reqparse
from app1.xxl_job_client import XXLJobClient
from flask import request
# 为了 teardown_xxl_client 引入app上下文
from app1 import app

ns_xxl = Namespace('nx_xxl', description='XXL-JOB Operations')


# 初始化客户端（从app配置获取基础URL）
# ---------------------------
# 优化后的客户端管理
# ---------------------------
def get_xxl_client():
    """请求级客户端单例（保持原有接口不变）"""
    if not hasattr(g, 'xxl_client'):
        g.xxl_client = XXLJobClient(current_app.config['XXL_JOB_ADMIN_URL'])

        # 自动注入请求头中的Cookie
        if 'Cookie' in request.headers:
            cookie = request.headers['Cookie']
            if 'XXL_JOB_LOGIN_IDENTITY=' in cookie:
                g.xxl_client._set_cookie(cookie)

    return g.xxl_client


def teardown_xxl_client(response):
    """请求结束后自动清理客户端"""
    if hasattr(g, 'xxl_client'):
        del g.xxl_client
    return response


# 在Flask中，teardown_xxl_client 函数是一个"teardown"函数，它需要在Flask应用的上下文中注册才能在每个请求结束后自动执行。
# 这个函数目前已经定义好了，但还没有被注册到Flask应用中。
# 要让这个函数生效，你需要在创建Flask应用的地方（通常是app.py或类似文件）进行注册。
app.teardown_appcontext(teardown_xxl_client)

# 响应模型
response_xxl_admin = ns_xxl.model('LogData', {
    'code': fields.Integer(description='状态码', example=200),
    'message': fields.String(description='消息', example='success'),
    'content': fields.String(description='返回内容', example=''),
    'data': fields.String(description='返回数据', example='')
})

# 定义外层的响应模型
response_xxl_model = ns_xxl.model('Response_xxl', {
    'message': fields.Nested(ns_xxl.model('Message_xxl', {
        "result": fields.Integer(description='查询结果返回值'),
        "result_text": fields.String(description='查询结果信息'),
        'count': fields.Integer(description='查询结果返回数据条数'),
        'data': fields.List(fields.Nested(response_xxl_admin))
    }))
})

# login 登录
# def login(self, username, password):

# 使用 Flask-RESTx 定义用户数据模型
login_model = ns_xxl.model('login', {
    'username': fields.String(required=True, description='username', example="admin"),
    'password': fields.String(required=True, description='password', example="123456"),
})

# trigger job 触发任务执行
# def trigger_job(self, job_id, executor_params=None, address_list=None, cookie=None):
trigger_job_model = ns_xxl.model('trigger_job', {
    'job_id': fields.Integer(required=True, description='任务id', example=2),
    'executor_params': fields.String(required=True, description='executor_params'),
    'address_list': fields.String(required=True, description='address_list'),
    'cookie': fields.String(required=True, description='cookie'),
})

# joblog_page  任务日志列表
# def get_joblog_page(self, start=0, length=10, job_group=-1, job_id=-1, log_status=-1, cookie=None):
joblog_page_model = ns_xxl.model('trigger_job', {
    'start': fields.Integer(required=True, description='start', example=0),
    'length': fields.Integer(required=True, description='length', example=10),
    'job_group': fields.Integer(required=True, description='job_group', example=2),
    'job_id': fields.Integer(required=True, description='任务id', example=-1),
    'log_status': fields.Integer(required=True, description='log_status', example=-1),
    'cookie': fields.String(required=True, description='cookie'),
})

# log_detail  任务日志详情
# def get_log_detail(self, log_id, from_line_num=1, cookie=None):
log_detail_model = ns_xxl.model('log_detailb', {
    'log_id': fields.Integer(required=True, description='任务id', example=100),
    'from_line_num': fields.Integer(required=True, description='开始行', example=1),
    'cookie': fields.String(required=True, description='cookie'),
})

# jobinfo_page  任务信息
# def get_jobinfo_page(self, start=0, length=10, job_group=2, triggerstatus=-1, job_desc="", executor_handler="",
#                          cookie=None):
jobinfo_page_model = ns_xxl.model('jobinfo_page', {
    'start': fields.Integer(required=True, description='start', example=0),
    'length': fields.Integer(required=True, description='length', example=10),
    'job_group': fields.Integer(required=True, description='job_group', example=2),
    'triggerstatus': fields.Integer(required=True, description='triggerstatus', example=-1),
    'job_desc': fields.String(required=True, description='job_desc'),
    'executor_handler': fields.String(required=True, description='executor_handler'),
    'cookie': fields.String(required=True, description='cookie'),
})

# jobgroup_page 执行器信息
# def get_jobgroup_page(self, start=0, length=10, cookie=None):
jobgroup_page_model = ns_xxl.model('jobgroup_page', {
    'start': fields.Integer(required=True, description='start', example=0),
    'length': fields.Integer(required=True, description='length', example=10),
    'cookie': fields.String(required=True, description='cookie'),
})


# ---------------------------
# 原有路由类（优化内部实现）
# ---------------------------
@ns_xxl.route('/xxl_login')
class XxlLoginResource(Resource):
    @ns_xxl.expect(login_model)
    @ns_xxl.marshal_with(response_xxl_model)
    def post(self):
        """ xxljob 登录"""
        data = request.get_json()
        client = get_xxl_client()
        result = client.login(data['username'], data['password'])

        response_data = {
            'message': {
                'result': result['code'],
                'result_text': result.get('msg', ''),
                'data': [result]
            }
        }

        # 登录成功时设置响应Cookie
        if result['code'] == 200:
            headers = {'Set-Cookie': result['data']['full_cookie']}
            return response_data, 200, headers

        return response_data, 401


@ns_xxl.route('/xxl_trigger_job')
class XxlTriggerJobResource(Resource):
    @ns_xxl.expect(trigger_job_model)
    @ns_xxl.marshal_with(response_xxl_model)
    def post(self):
        """ xxljob 触发任务执行"""
        data = request.get_json()
        client = get_xxl_client()
        result = client.trigger_job(
            job_id=data['job_id'],
            executor_params=data.get('executor_params'),
            address_list=data.get('address_list')
        )

        return {
            'message': {
                'result': result['code'],
                'result_text': result.get('msg', ''),
                'data': [result]
            }
        }


@ns_xxl.route('/xxl_joblog_page')
class XxlJoblogPageResource(Resource):
    @ns_xxl.expect(joblog_page_model)
    @ns_xxl.marshal_with(response_xxl_model)
    def post(self):
        """ xxljob 查询任务日志列表"""
        data = request.get_json()
        client = get_xxl_client()
        result = client.get_joblog_page(
            start=data['start'],
            length=data['length'],
            job_group=data['job_group'],
            job_id=data['job_id'],
            log_status=data['log_status']
        )

        return {
            'message': {
                'result': result['code'],
                'result_text': result.get('msg', ''),
                'count': len(result.get('data', {}).get('records', [])),
                'data': [result]
            }
        }


@ns_xxl.route('/xxl_log_detail')
class XxlLogDetailResource(Resource):
    @ns_xxl.expect(log_detail_model)
    @ns_xxl.marshal_with(response_xxl_model)
    def post(self):
        """ xxljob 查询执行日志详情"""
        data = request.get_json()
        client = get_xxl_client()
        result = client.get_log_detail(
            log_id=data['log_id'],
            from_line_num=data['from_line_num']
        )

        return {
            'message': {
                'result': result['code'],
                'result_text': result.get('msg', ''),
                'data': [result]
            }
        }


@ns_xxl.route('/xxl_jobinfo_page')
class XxlJobinfoPageResource(Resource):
    @ns_xxl.expect(jobinfo_page_model)
    @ns_xxl.marshal_with(response_xxl_model)
    def post(self):
        """ xxljob 查询任务列表"""
        data = request.get_json()
        client = get_xxl_client()
        result = client.get_jobinfo_page(
            start=data['start'],
            length=data['length'],
            job_group=data['job_group'],
            job_desc=data.get('job_desc', ''),
            executor_handler=data.get('executor_handler', '')
        )

        return {
            'message': {
                'result': result['code'],
                'result_text': result.get('msg', ''),
                'count': len(result.get('data', {}).get('records', [])),
                'data': [result]
            }
        }


@ns_xxl.route('/xxl_jobgroup_page')
class XxlJobgroupPageResource(Resource):
    @ns_xxl.expect(jobgroup_page_model)
    @ns_xxl.marshal_with(response_xxl_model)
    def post(self):
        """ xxljob 查询执行器列表"""
        data = request.get_json()
        client = get_xxl_client()
        result = client.get_jobgroup_page(
            start=data['start'],
            length=data['length']
        )

        return {
            'message': {
                'result': result['code'],
                'result_text': result.get('msg', ''),
                'count': len(result.get('data', {}).get('records', [])),
                'data': [result]
            }
        }
